﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace MyCommonPortableLib.Common
{
    public static class CopyObjectTo<T>
    {

        /// <summary>
        /// Copy all object properties from SourceObject and returns new instance 
        /// </summary>
        /// <param name="SourceOdbject"></param>
        /// <returns>new instance of T</returns>
        public static T FromSource(Object SourceOdbject)
        {
            try
            {
                var dest = (Object)Activator.CreateInstance(typeof(T));
                var sourceProps = SourceOdbject.GetType().GetRuntimeProperties();

                foreach (PropertyInfo d in typeof(T).GetRuntimeProperties())
                {
                    PropertyInfo sp = (from c in sourceProps
                                       where
                                           c.Name == d.Name
                                       select c).FirstOrDefault();

                    if (sp != null && d.CanWrite && sp.CanRead)
                        d.SetValue(dest, sp.GetValue(SourceOdbject, null), null);
                }

                return (T)dest;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// Copy all properties from source to destination
        /// </summary>
        /// <param name="destination"></param>
        /// <param name="source"></param>
        public static void Copy(T destination, Object source)
        {
            try
            {
                var sourceProps = source.GetType().GetRuntimeProperties();

                foreach (PropertyInfo d in typeof(T).GetRuntimeProperties())
                {
                    PropertyInfo sp = (from c in sourceProps
                                       where
                                           c.Name == d.Name
                                       select c).FirstOrDefault();

                    if (sp != null && d.CanWrite && sp.CanRead && sp.GetValue(source, null) != null)
                        d.SetValue(destination, sp.GetValue(source, null), null);

                }

            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}
